// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.TeamFoundation.Migration.Toolkit.VC
{
    /// <summary>
    /// The change grouping manager contains the version control session, migration direction
    /// and the source and target item serializer instances.
    /// </summary>
    public abstract class ChangeGroupingMananger
    {
        /// <summary>
        /// Creates a change grouping manager using the provided parameters.
        /// </summary>
        /// <param name="sourceSerializer">The soruce item type serializer</param>
        /// <param name="targetSerializer">The target item type serializer</param>
        /// <param name="session">The migration session that is executing.</param>
        /// <param name="direction">The direction of the migration</param>
        protected ChangeGroupingMananger(
            IMigrationItemSerializer sourceSerializer,
            IMigrationItemSerializer targetSerializer,
            VersionControlSession session,
            MigrationDirection direction)
        {
            m_targetSerializer = targetSerializer;
            m_sourceSerializer = sourceSerializer;
            m_session = session;
            m_direction = direction;
        }

        /// <summary>
        /// The highwater mark of the last successfully migrated change operation
        /// </summary>
        public virtual IHighWaterMark LastHighWaterMark
        {
            get
            {
                return m_lastHwm;
            }
            set
            {
                m_lastHwm = value;
            }
        }

        /// <summary>
        /// The source item serializer
        /// </summary>
        public IMigrationItemSerializer SourceSerializer
        {
            get
            {
                return m_sourceSerializer;
            }
        }

        /// <summary>
        /// The target item serialzier
        /// </summary>
        public IMigrationItemSerializer TargetSerializer
        {
            get
            {
                return m_targetSerializer;
            }
        }

        /// <summary>
        /// The version control session that is executing.
        /// </summary>
        public VersionControlSession Session
        {
            get
            {
                return m_session;
            }
        }

        /// <summary>
        /// The direction of the migration
        /// </summary>
        public MigrationDirection Direction
        {
            get
            {
                return m_direction;
            }
        }

        /// <summary>
        /// Identifies and returns the next ChangeGrouping instance for migration.  It is possible for this
        /// method to return the same grouping multiple times if the grouping's status has not changed.  Only
        /// change groupings for the proper session are returned.  By default this uses a transactional
        /// context returned by DataAccessManager.Current.StartTransaction().
        /// </summary>
        /// <returns>The next available ChangeGrouping</returns>
        public abstract ChangeGrouping Next();

        /// <summary>
        /// Identifies and demotes any change groupings in the current session whose status is InProgress
        /// to the Pending state.
        /// This method is called as a part of crash recovery to ensure that any pending operations are reverted
        /// so they can be retried.  By default this uses a transactional context returned 
        /// by DataAccessManager.Current.StartTransaction().
        /// </summary>
        /// <returns>The number of change groupings reverted from "InProgress" to "Pending"</returns>
        public abstract int DemoteInProgressActionsToPending();


        /// <summary>
        /// Identifies and promotes any change groupings in the current session whose status is Analysis
        /// to the Pending state.
        /// This method is called during the analysis phase when the items in the analysis 
        /// state are ready for migration.  The promotion occurs in the transaction context provided.
        /// </summary>
        /// <param name="trx">The transaction context to perform the promotion.</param>
        /// <returns>The number of change groupings reverted from "Analysis" to "Pending"</returns>
        public abstract int PromoteAnalysisToPending();

        /// <summary>
        /// Identifies and demotes any change groupings in the current session whose status is InProgress
        /// to the Pending state.
        /// This method is called as a part of crash recovery to ensure that any pending operations are reverted
        /// so they can be retried.  By default this uses a transactional context returned 
        /// by DataAccessManager.Current.StartTransaction().
        /// </summary>
        /// <param name="trx">The transaction context to perform the promotion.</param>
        /// <returns>The number of change groupings reverted from "InProgress" to "Pending"</returns>
        public abstract int DemoteInProgressActionsToPending(IMigrationTransaction trx);


        /// <summary>
        /// Identifies and promotes any change groupings in the current session whose status is Analysis
        /// to the Pending state.
        /// This method is called during the analysis phase when the items in the analysis 
        /// state are ready for migration.  The promotion occurs in the transaction context provided.
        /// </summary>
        /// <param name="trx">The transaction context to perform the promotion.</param>
        /// <returns>The number of change groupings reverted from "Analysis" to "Pending"</returns>
        public abstract int PromoteAnalysisToPending(IMigrationTransaction trx);

        /// <summary>
        /// Creates a new change grouping with the specified name.
        /// </summary>
        /// <param name="groupName">The name of the new change grouping.</param>
        /// <returns>The newly created change grouping</returns>
        public abstract ChangeGrouping Create(string groupName);

        IMigrationItemSerializer m_sourceSerializer;
        IMigrationItemSerializer m_targetSerializer;
        VersionControlSession m_session;
        MigrationDirection m_direction;
        IHighWaterMark m_lastHwm;
    }

}
